package com.ml.mall.service.credit.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ml.mall.bean.base.ApiRestResult;
import com.ml.mall.bean.page.PageExtend;
import com.ml.mall.bean.req.credit.CreditNewDto;
import com.ml.mall.bean.req.credit.CreditRecordNewDto;
import com.ml.mall.bean.req.credit.CreditRecordQueryDto;
import com.ml.mall.bean.res.credit.CreditRecordQueryRes;
import com.ml.mall.consts.CommonConsts;
import com.ml.mall.entity.credit.SysCredit;
import com.ml.mall.entity.credit.SysCreditRecord;
import com.ml.mall.entity.sys.SysUser;
import com.ml.mall.enums.CommonEnum;
import com.ml.mall.enums.CreditEnum;
import com.ml.mall.enums.SysSeqNameEnum;
import com.ml.mall.exception.BizException;
import com.ml.mall.mapper.credit.SysCreditMapper;
import com.ml.mall.mapper.credit.SysCreditRecordMapper;
import com.ml.mall.security.JwtUtil;
import com.ml.mall.service.asyn.AuthMailServiceImplAsyn;
import com.ml.mall.service.common.CommonSeqService;
import com.ml.mall.service.credit.SysCreditRecordService;
import com.ml.mall.service.credit.SysCreditService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Service
@Slf4j
public class SysCreditRecordServiceImpl extends ServiceImpl<SysCreditRecordMapper, SysCreditRecord> implements SysCreditRecordService {

    @Autowired
    private SysCreditRecordMapper sysCreditRecordMapper;
    @Autowired
    private CommonSeqService commonSeqService;
    @Autowired
    private SysCreditMapper sysCreditMapper;
    @Autowired
    private SysCreditService sysCreditService;
    @Autowired
    private AuthMailServiceImplAsyn mailService;

    @Override
    @Transactional
    public ApiRestResult createCreditRecord(CreditRecordNewDto dto) {
        //目标不存在余额信息时，先为其创建余额信息
        QueryWrapper<SysCredit> countWrapper = new QueryWrapper<>();
        countWrapper.eq("company_id", dto.getCompanyId());
        if(CommonConsts.FIXED_NUM_ZERO == sysCreditMapper.selectCount(countWrapper)){
            CreditNewDto creditNewDto = new CreditNewDto();
            creditNewDto.setCompanyId(dto.getCompanyId());
            creditNewDto.setCreditBalance(BigDecimal.ZERO);
            sysCreditService.createCredit(creditNewDto);
        }

        //判断公司余额是否充足
        CreditRecordQueryDto queryDto = new CreditRecordQueryDto();
        queryDto.setCompanyId( dto.getCompanyId());
        BigDecimal initialBalance = sysCreditMapper.selectByCompanyId(dto.getCompanyId()).getCreditBalance();//初始余额
        log.info("initialBalance===={}",initialBalance);
        BigDecimal changeMoney = dto.getChangeMoney().abs();
        BigDecimal finalBalance = BigDecimal.ZERO;
        if(!dto.getType().equals(CreditEnum.CREDIT_ADD.getType())){
            changeMoney = changeMoney.negate();
        }
        finalBalance = initialBalance.add(changeMoney);

        //最终余额
        log.info("finalBalance====={}",finalBalance);
        log.info("changeMoney====={}",changeMoney);
        if(finalBalance.compareTo(BigDecimal.ZERO) < 0){
            throw new BizException(CommonEnum.COMPANY_CREDIT_NOT_ENOUGH);
        }

        SysUser currentUser = JwtUtil.getCurrentUser();
        SysCreditRecord sysCreditRecord = new SysCreditRecord();
        sysCreditRecord.setCompanyId(dto.getCompanyId());
        sysCreditRecord.setUpdaterAcc(currentUser.getAcc());
        sysCreditRecord.setChangeType(dto.getType());

        if(dto.getChangeId() == null){
            Long changeId = commonSeqService.nextSysOrderSeq(SysSeqNameEnum.SEQ_CREDIT_RECODE.getCode(),0);
            sysCreditRecord.setChangeId(changeId);
        }else{
            sysCreditRecord.setChangeId(dto.getChangeId());
        }

        if(dto.getType() == CreditEnum.CREDIT_ADD.getType()){
            sysCreditRecord.setChangeName(CreditEnum.CREDIT_ADD.getChangeName());
            sysCreditRecord.setChangeMoney(dto.getChangeMoney().abs());//肯定是正数
        }else if(dto.getType() == CreditEnum.CREDIT_REDUCE.getType()){
            sysCreditRecord.setChangeName(CreditEnum.CREDIT_REDUCE.getChangeName());
            sysCreditRecord.setChangeMoney(dto.getChangeMoney().abs().negate()); //肯定是负数
        }else{
            sysCreditRecord.setChangeName(String.valueOf(dto.getOid()));
            sysCreditRecord.setChangeMoney(dto.getChangeMoney().abs().negate()); //肯定是负数
        }
        int isAdd = sysCreditRecordMapper.insert(sysCreditRecord);
        if(isAdd < 1){
            throw new BizException(CommonEnum.INSERT_ERROR);
        }
        //变更credit
        sysCreditMapper.updateCreditBalanceByCompanyId(sysCreditRecord.getChangeMoney(),dto.getCompanyId());
        //发送通知邮件
        mailService.updateCreditMailAsyn(currentUser, dto.getCompanyId(), initialBalance, finalBalance);
        return ApiRestResult.ok();
    }

    @Override
    public PageExtend<CreditRecordQueryRes> queryPageCreditRecord(CreditRecordQueryDto dto) {
        PageExtend<CreditRecordQueryRes> page = new PageExtend(dto.getPageIndex(),dto.getPageNum());
        List<CreditRecordQueryRes> creditRecordResList = sysCreditRecordMapper.selectPageCreditRecord(dto);
        Long count = sysCreditRecordMapper.selectCountCreditRecord(dto);
        BigDecimal allMoney = sysCreditMapper.selectByCompanyId(dto.getCompanyId()).getCreditBalance();
        page.setTotal(Long.valueOf(count).intValue());
        page.setRecords(creditRecordResList);
        page.setAllMoney(allMoney != null ? allMoney : BigDecimal.ZERO);
        return page;
    }

    @Override
    public BigDecimal getCompanyCredit(CreditRecordQueryDto dto) {
        return sysCreditRecordMapper.sumCreditRecordMoney(dto);
    }
}
